﻿using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Linq.Expressions;
using System.Text;

namespace Ue.Core.TreeViews
{
    public class TreeView<T>
        where T : ITreeNode<T>
    {
        #region 构造和字段

        protected LazyField<IList<T>> lazyCacheNodes;
        private Func<TreeView<T>, T,T> buildNode;

        public TreeView(Func<TreeView<T>,T,T> buildNode)
        {
            this.lazyCacheNodes = new LazyField<IList<T>>(() => new List<T>());
            this.buildNode = buildNode;
            //this.Name = treeName;
        }

        #endregion

        #region 公共属性

        //public string Name { get; set; }

        public virtual IEnumerable<T> Items
        {
            get { return this.lazyCacheNodes.Value; }
        }

        public virtual IEnumerable<T> ChildNodes
        {
            get { return this.Items.Where(item => item.Parent == null); }
        }

        #endregion

        #region Add / Remove

        public virtual void AddOrUpdate(T node)
        {
            if (node == null)
            {
                return;
            }

            this.CheckNode(node);

            if (node.Parent != null && !this.Items.Contains(node.Parent))
            {
                this.AddOrUpdate(node.Parent);
            }

            int index = this.lazyCacheNodes.Value.IndexOf(node);
            if (index == -1)
            {
                this.lazyCacheNodes.Value.Add(node);
            }
            else
            {
                this.lazyCacheNodes.Value[index] = node;
            }
        }

        public virtual void Remove(T node)
        {
            if (this.Items.Contains(node))
            {
                this.lazyCacheNodes.Value.Remove(node);
            }
        }

        private void CheckNode(T node)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (!node.TreeView.Equals(this))
            {
                throw new ArgumentOutOfRangeException("node不是从当前TreeView创建的，不能添加至当前TreeView。");
            }
        }
        #endregion

        #region CreateNode

        public T CreateNode()
        {
            return this.CreateNode(default(T));
        }
        public T CreateNode(T parentNode)
        {
            return this.buildNode(this,parentNode);
        }

        #endregion
    }
}
